package com.tetris.controller;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;

import com.tetris.entities.Ground;
import com.tetris.entities.Shape;
import com.tetris.entities.ShapeFactory;
import com.tetris.view.GamePanel;
import com.tetris.view.ScorePanel;

import static com.tetris.util.Constants.*;

/**
 * @author 吴松 create the file at 2013-4-7 <br>
 *         is com.itcast.tetris.controller.Controller <br>
 */
public class Controller extends KeyAdapter {

	private Shape shape;
	private final ShapeFactory shapeFactroy;
	private final Ground ground;
	private final GamePanel gamePanel;
	private final ScorePanel scorePanel;
	private final JFrame jframe;

	/** 当前得分 */
	private int score;
	private int linesCount;
	/** 连续删除两行的次数 */
	private int line2Count;
	/** 连续删除三行的次数 */
	private int line3Count;
	/** 连续删除四行的次数 */
	private int line4Count;
	/** 方块下落速度 */
	private long speed = 300;

	/** 游戏状态，0默认未开始，1游戏中，2暂停，3结束 */
	private int gameStatus = GAME_STAUTS_DEFAULT;

	@Override
	public void keyPressed(final KeyEvent e) {
		if(gameStatus!=GAME_STAUTS_GAMING){
			return;
		}
		switch (e.getKeyCode()) {
			case KeyEvent.VK_UP:
				if (ground.isMoveable(shape, Shape.ROTATE)) {
					shape.rotate();
					gamePanel.display(ground, shape);
				}
				break;
			case KeyEvent.VK_DOWN:
				autoMoveDown(shape);
				break;
			case KeyEvent.VK_LEFT:
				if (ground.isMoveable(shape, Shape.LEFT)) {
					shape.moveLeft();
					gamePanel.display(ground, shape);
				}
				break;
			case KeyEvent.VK_RIGHT:
				if (ground.isMoveable(shape, Shape.RIGHT)) {
					shape.moveRight();
					gamePanel.display(ground, shape);
				}
		}
	}

	private void newGame() {
		shape = shapeFactroy.getShape();
		score = 0;
		linesCount = 0;
		line2Count = 0;
		line3Count = 0;
		line4Count = 0;
		speed = 300;
		ground.clearObstacles();
		scorePanel.updateText(score, linesCount, line2Count, line3Count, line4Count);
		startGame();
	}

	private void startGame() {
		gameStatus = GAME_STAUTS_GAMING;
		new Thread(new ShapeDownListener()).start();
		gamePanel.requestFocus();
	}

	public Controller(final ShapeFactory shapeFactory, final Ground ground, final GamePanel gamePanel, final ScorePanel scorePanel, final JFrame jframe) {
		this.shapeFactroy = shapeFactory;
		this.ground = ground;
		this.gamePanel = gamePanel;
		this.scorePanel = scorePanel;
		this.jframe = jframe;

		this.ground.setController(this);
		this.scorePanel.bindControllButtonAction(new MouseAdapter(){
			@Override
			public void mouseClicked(MouseEvent e) {
				switch (gameStatus) {
					case GAME_STAUTS_OVER:
					case GAME_STAUTS_DEFAULT:
						scorePanel.changeControllButtonText("暂停");
						jframe.setTitle(GAME_NAME + " - 游戏中···");
						newGame();
						break;
					case GAME_STAUTS_GAMING:
						scorePanel.changeControllButtonText("继续游戏");
						jframe.setTitle(GAME_NAME + " - 游戏已暂停");
						gameStatus = GAME_STAUTS_SUSPEND;
						break;
					case GAME_STAUTS_SUSPEND:
						scorePanel.changeControllButtonText("暂停");
						jframe.setTitle(GAME_NAME + " - 游戏中···");
						startGame();
						break;
				}
			}

		});
	}

	public void onDeleteLines(final int count) {
		linesCount += count;
		if (count == 1) {
			score += 10;
		} else if (count == 2) {
			score += 30;
			line2Count++;
		} else if (count == 3) {
			score += 60;
			line3Count++;
		} else if (count == 4) {
			score += 100;
			line4Count++;
		}
		if (score > 1000) {
			speed = 150;
		} else if (score > 500) {
			speed = 200;
		} else if (score > 100) {
			speed = 250;
		}
		scorePanel.updateText(score, linesCount, line2Count, line3Count, line4Count);
	}

	private synchronized void autoMoveDown(final Shape shape) {
		if (ground.isMoveable(shape, Shape.DOWN)) {
			shape.moveDown();
			gamePanel.display(ground, shape);
		} else {
			if (ground.isGameOver()) {
				gameStatus = GAME_STAUTS_OVER;
				scorePanel.changeControllButtonText("重新开始");
				scorePanel.controllButtonFocus();
				jframe.setTitle(GAME_NAME + " - 游戏已结束");
			} else {
				// 如果不能移动，则让图形成为容器的障碍物(固定图形)，并重新生成一个图形
				ground.accept(shape);
				this.shape = shapeFactroy.getShape();
			}
		}
	}

	private class ShapeDownListener implements Runnable {
		@Override
		public void run() {
			while (gameStatus == GAME_STAUTS_GAMING) {
				autoMoveDown(shape);
				try {
					Thread.sleep(speed);
				} catch (final InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}